package com.adcc.ags.cgw.service;

import com.adcc.ags.cgw.configuration.BlackListFactory;
import com.adcc.ags.cgw.entity.msg.*;
import com.adcc.ags.cgw.entity.msg.MsgType;
import com.adcc.ags.cgw.entity.user.*;
import com.adcc.ags.cgw.proxy.MsgProxy;
import com.adcc.ags.cgw.utils.Constant;
import com.adcc.utility.log.Log;
import com.adcc.utility.msg620.ACARS620Msg;
import com.adcc.utility.msg620.ACARS620Parser;
import com.google.common.base.Optional;
import com.google.common.base.Strings;

import java.util.List;
import java.util.regex.Pattern;

/**
 * 消息过滤服务实现类
 */
public class MsgFilterServiceImpl extends MsgFilterService{

    /**
     * 将路由规则转化为正则表达式
     * @param route
     * @return
     */
    private String formatRouteToRegex(String... route){
        String strRegex = Strings.nullToEmpty("");
        if(route != null && route.length > 0){
            for(int i=0; i< route.length; i++){
                if(i == route.length -1){
                    strRegex += route[i].replace(Constant.CHAR_USER_ROUTE,Constant.CHAR_USER_REGEX);
                }else{
                    strRegex += route[i].replace(Constant.CHAR_USER_ROUTE,Constant.CHAR_USER_REGEX) + "|";
                }
            }
        }
        return strRegex;
    }

    @Override
    protected boolean matchRoute(String element, String... route) {
        String strRegex = formatRouteToRegex(route);
        return Pattern.matches(strRegex, element);
    }

    @Override
    protected boolean matchRoute(String[] element, String... route) {
        String strRegex = formatRouteToRegex(route);
        for(String elt : element){
            if(Pattern.matches(strRegex,elt)){
                return true;
            }
        }
        return false;
    }

    @Override
    protected boolean matchRoute(String element, int start, String route) {
        String strRegex = formatRouteToRegex(route);
        return Pattern.compile(strRegex).matcher(element).find(start);
    }

    @Override
    protected boolean filter(CGWMsg msg) {
        try{
            List<BlackListUser> invalidUserList = BlackListFactory.getInstance().getBlackList();
            if(invalidUserList.size() > 0){
                for(BlackListUser invalidUser : invalidUserList){
                    if(msg.getSender().equals(invalidUser.getId())){

                        if(msg.getType() == MsgType.UPLINK){
                            byte[] buffer = msg.getMsg().getContent();
                            Optional<ACARS620Msg> optional = ACARS620Parser.parse(new String(buffer, 0, buffer.length));
                            if(optional.isPresent()){

                                // 匹配接收地址
                                if(invalidUser.getRecvAddress() != null && invalidUser.getRecvAddress().length > 0){
                                    if(matchRoute(optional.get().getRecvAddress(),invalidUser.getRecvAddress())){
                                        return true;
                                    }
                                }

                                // 匹配发送地址
                                if(!Strings.isNullOrEmpty(invalidUser.getSendAddress())){
                                    if(matchRoute(optional.get().getSendAddress(), invalidUser.getSendAddress())){
                                        return true;
                                    }
                                }

                                // 匹配报文类型
                                if(invalidUser.getSmi() != null && invalidUser.getSmi().length > 0){
                                    if(matchRoute(optional.get().getSmi(),invalidUser.getSmi())){
                                        return true;
                                    }
                                }

                                // 匹配机尾号
                                if(invalidUser.getAn() != null && invalidUser.getAn().length > 0){
                                    if(matchRoute(optional.get().getAn(), invalidUser.getAn())){
                                        return true;
                                    }
                                }

                                // 匹配关键字
                                if(invalidUser.getSpecLabel() != null && !Strings.isNullOrEmpty(invalidUser.getSpecLabel().getContent()) && invalidUser.getSpecLabel().getIndex() >=0) {
                                    if(matchRoute(optional.get().getFreeText(), invalidUser.getSpecLabel().getIndex(), invalidUser.getSpecLabel().getContent())){
                                        return true;
                                    }
                                }
                            }
                        }else{
                            byte[] buffer = msg.getMsg().getContent();
                            String strMsg = new String(buffer,0,buffer.length);

                            // 匹配关键字
                            if(invalidUser.getSpecLabel() != null && !Strings.isNullOrEmpty(invalidUser.getSpecLabel().getContent()) && invalidUser.getSpecLabel().getIndex() >=0) {
                                if(matchRoute(strMsg, invalidUser.getSpecLabel().getIndex(), invalidUser.getSpecLabel().getContent())){
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }catch (Exception ex){
            Log.error(MsgFilterService.class.getName(), "filter() error",ex);
        }
        return false;
    }

    @Override
    public void onReceive(Object message) {
        super.onReceive(message);
        try{
            CGWMsg cgwMsg = (CGWMsg)message;
            if(cgwMsg != null){

                    // 对上行和地地报文进行过滤,符合黑名单过滤规则的报文不上发
                    if(filter(cgwMsg)){
                        Log.error(MsgFilterService.class.getName(), "filter blacklist user uplink message:\r\n" + cgwMsg.getMsg().toString());
                        MsgProxy.getInstance().getMsgSaveActor().tell(new TrafficMsg(cgwMsg.getId(),Constant.ERROR_CODE_FILTERFAILED,""),this.getSelf());
                    }else{
                        MsgProxy.getInstance().getMsgRouteActor().tell(cgwMsg, this.getSelf());
                    }
            }else{
                Log.error(MsgFilterService.class.getName(),"receive invalid uplink message");
                unhandled(message);
            }
        }catch (Exception ex){
            Log.error(MsgFilterService.class.getName(),"onReceive() error",ex);
        }
    }
}
